#pragma once
namespace graph_virtual
{
//Singleton, which stores all app data
struct global_data_t
{
    graph_basic::high_way_dict_t high_way_dict;
    virtual_graph_view_ptr_t all_way_view_;
    virtual_graph_view_ptr_t motor_way_view_;
    virtual_graph_view_ptr_t bicycle_view_;
    virtual_graph_view_ptr_t foot_way_view_t_;
    virtual_graph_view_ptr_t current_view_;
    std::string current_path_type_;
    virtual_graph_ptr_t graph_;
    
    global_data_t();
    void set_new_graph(virtual_graph_ptr_t new_graph);
    void set_new_view(std::string path_type);
    graph_basic::graph_view_ptr_t get_current_view_for_graph(graph_basic::graph_ptr_t graph);   
};

struct global
{
   static global_data_t& get_instance()
   {
      return global_;
   }
private:
   static global_data_t global_;
};
inline global_data_t::global_data_t()
{
   //0 - reserved for no value
   //ATTENTION: IF CHANGED VALUES in osm, YOU HAVE TO SYNC WITH LOGIC OF
   //MotorWayPredicate, ByciclePredicate , FootPredicate
   high_way_dict["motorway"] = 1;//0x0100;
   high_way_dict["trunk"] = 2;//0x0200;
   high_way_dict["primary"] = 3;//0x0300;
   high_way_dict["secondary"] = 4;//0x0400;
   high_way_dict["tertiary"] = 5;//0x0500;
   high_way_dict["unclassified"] = 6;//0x0600;
   high_way_dict["residential"] = 7;//0x0700;
   high_way_dict["living_street"] = 8;//0x0800;
   high_way_dict["road"] = 9;//0x0900;
   high_way_dict["pedestrian"] = 10;//0x0A00;
   high_way_dict["path"] = 11;//0x0B00;
   high_way_dict["bridleway"] = 12;//0x0C00;
   high_way_dict["cycleway"] = 13;//0x0D00;
   high_way_dict["footway"] = 14;//0x0E00;
}
inline void global_data_t::set_new_graph(virtual_graph_ptr_t new_graph)
{
   graph_ = new_graph;

   all_way_view_ = virtual_graph_view_ptr_t(new all_way_view_t(graph_));
   motor_way_view_ = virtual_graph_view_ptr_t(new motor_way_view_t(graph_));
   bicycle_view_ = virtual_graph_view_ptr_t(new bicycle_way_view_t(graph_));
   foot_way_view_t_ = virtual_graph_view_ptr_t(new foot_way_view_t(graph_));

   set_new_view(graph_basic::PATH_TYPE_ALL);
}
inline void global_data_t::set_new_view(std::string path_type)
{
   current_path_type_ = path_type;
   if (path_type == graph_basic::PATH_TYPE_ALL)
   {
      current_view_ = all_way_view_;
   }
   else if (path_type == graph_basic::PATH_TYPE_MOTOR)
   {
      current_view_ = motor_way_view_;
   }
   else if (path_type == graph_basic::PATH_TYPE_BICYCLE)
   {
      current_view_ = bicycle_view_;
   }
   else if (path_type == graph_basic::PATH_TYPE_FOOT)
   {
      current_view_ = foot_way_view_t_;
   }
}

inline graph_basic::graph_view_ptr_t global_data_t::get_current_view_for_graph(graph_basic::graph_ptr_t graph)
{
   graph_basic::graph_view_ptr_t view_ptr;
   if (current_path_type_ == graph_basic::PATH_TYPE_ALL)
   {
      view_ptr.reset( new graph_basic::graph_all_way_view_t(graph));
   }
   else if (current_path_type_ == graph_basic::PATH_TYPE_MOTOR)
   {
      view_ptr.reset( new graph_basic::graph_motor_way_view_t(graph));
   }
   else if (current_path_type_ == graph_basic::PATH_TYPE_BICYCLE)
   {
      view_ptr.reset( new graph_basic::graph_bicycle_view_t(graph));
   }
   else if (current_path_type_ == graph_basic::PATH_TYPE_FOOT)
   {
      view_ptr.reset( new graph_basic::graph_foot_way_view_t(graph));
   }
   return view_ptr;
}
}